﻿using Newtonsoft.Json;
using PMIS.Common;
using PMIS.Common.Dialog;
using PMIS.Controls;
using PMIS.HttpRequest;
using PMIS.Shared.DTO;
using PMIS.Shared.Models;
using System.Collections.ObjectModel;
using System.ComponentModel.DataAnnotations;
using System.Windows.Input;

namespace PMIS.ViewModels.User
{
    public class AddEditUserViewModel : DialogViewModelBase
    {
        private readonly HttpService _httpService;

        public AddEditUserViewModel(HttpService httpService)
        {
            _httpService = httpService;

            this.User = new UserDto();

            LoadNavDept();

            LoadRoleList();
        }

        private List<RoleDto> _roleList;

        public List<RoleDto> RoleList
        {
            get => _roleList;
            set
            {
                SetProperty(ref _roleList, value);
            }
        }

        private ObservableCollection<RoleDto> _selectedRoleList = new ObservableCollection<RoleDto>();

        public ObservableCollection<RoleDto> SelectedRoleList
        {
            get => _selectedRoleList;
            set
            {
                SetProperty(ref _selectedRoleList, value);
            }
        }

        private DepartmentDto _selectedDeptItem;
        public DepartmentDto SelectedDeptItem
        {
            get => _selectedDeptItem;
            set
            {
                SetProperty(ref _selectedDeptItem, value);
            }
        }

        private List<DepartmentDto>? _allDeptList = new List<DepartmentDto>();
        public List<DepartmentDto>? AllDeptList
        {
            get
            {
                return _allDeptList;
            }
            set
            {
                SetProperty(ref _allDeptList, value);
            }
        }

        private List<DepartmentDto>? _treeDeptList;
        public List<DepartmentDto>? TreeDeptList
        {
            get
            {
                return _treeDeptList;
            }
            set
            {
                SetProperty(ref _treeDeptList, value);
            }
        }

        private async void LoadRoleList()
        {
            var response = await _httpService.GetAsync(Api.ROLE_GET_LIST);
            if (response?.code == 1)
            {
                var data = JsonConvert.DeserializeObject<PagingModel<RoleDto>>(JsonConvert.SerializeObject(response.data));
                this.RoleList = data.Items.OrderBy(p => p.Sort).ToList();

                this.SelectedRoleList = new ObservableCollection<RoleDto>();

                if (!string.IsNullOrEmpty(this.User.RoleId))
                {
                    List<string> rolesid = JsonConvert.DeserializeObject<List<string>>(this.User.RoleId);
                    this.SelectedRoleList = new ObservableCollection<RoleDto>(this.RoleList.Where(p => rolesid.Contains(p.Id)));
                }
            }
        }

        private async void LoadNavDept()
        {
            var response = await _httpService.GetAsync(Api.DEPT_GET_LIST);
            if (response?.code == 1)
            {
                var data = JsonConvert.DeserializeObject<PagingModel<DepartmentDto>>(JsonConvert.SerializeObject(response.data));
                AllDeptList = data.Items.OrderBy(p => p.Sort).ToList();

                if (!string.IsNullOrEmpty(this.User.DepartmentId))
                {
                    this.SelectedDeptItem = AllDeptList.FirstOrDefault(x => x.Id == this.User.DepartmentId);
                }

                LoadTreeDeptList();
            }
        }

        private void LoadTreeDeptList()
        {
            var deptList = AllDeptList;
            TreeDeptList = new List<DepartmentDto>(deptList.Where(x => x.ParentId == null));
            foreach (var item in TreeDeptList)
            {
                LoadChildDeptList(item);
            }
        }

        public void LoadChildDeptList(DepartmentDto dept)
        {
            var deptList = AllDeptList;
            dept.Children = deptList.Where(x => x.ParentId == dept.Id).ToList();
            foreach (var subitem in dept.Children)
            {
                // Recursive call
                LoadChildDeptList(subitem);
            }
        }

        private List<DepartmentDto>? _deptList;
        public List<DepartmentDto>? DeptList
        {
            get { return _deptList; }
            set { SetProperty(ref _deptList, value); }
        }

        private UserDto _user;

        public UserDto User
        {
            get { return _user; }
            set { SetProperty(ref _user, value); }
        }

        private string _errorMessage;

        public string ErrorMessage
        {
            get { return _errorMessage; }
            set { SetProperty(ref _errorMessage, value); }
        }

        private ICommand _saveCommand;
        public ICommand SaveCommand
        {
            get
            {
                if (_saveCommand == null)
                {
                    _saveCommand = new DelegateCommand(OnSave);
                }
                return _saveCommand;
            }
        }

        private ICommand _cancelCommand;
        public ICommand CancelCommand
        {
            get
            {
                if (_cancelCommand == null)
                {
                    _cancelCommand = new DelegateCommand(OnCancel);
                }
                return _cancelCommand;
            }
        }

        private async void OnSave()
        {
            var validationResults = new List<ValidationResult>();
            var isFormValid = Validator.TryValidateObject(User, new ValidationContext(User), validationResults, true);
            if (!isFormValid)
            {
                this.ErrorMessage = validationResults?.FirstOrDefault()?.ErrorMessage ?? "";
                return;
            }
            else
            {
                this.ErrorMessage = string.Empty;
            }

            bool result = false;
            if (string.IsNullOrEmpty(this.User.Id))
            {
                result = await Add();
            }
            else
            {
                result = await Edit();
            }

            if (result)
            {
                CloseDialog(new DialogResult(ButtonResult.OK));
            }
        }

        private async Task<bool> Add()
        {
            if (_selectedDeptItem != null)
            {
                _user.DepartmentId = _selectedDeptItem.Id;
            }
            var response = await _httpService.PostAsync(Api.USER_ADD, _user);
            if (response?.code == 1)
            {
                long r = (long)response.data;
                return r == 1;
            }
            else
            {
                var message = response?.msg ?? "保存失败";
                ToastManager.ShowToast(message);
            }
            return false;
        }

        private async Task<bool> Edit()
        {
            if (_selectedDeptItem != null)
            {
                _user.DepartmentId = _selectedDeptItem.Id;
            }

            if (_selectedRoleList.Count > 0)
            {
                _user.RoleId = _selectedRoleList.Select(x => x.Id).ToJson();
            }
            var response = await _httpService.PutAsync(Api.USER_UPDATE, _user);
            if (response?.code == 1)
            {
                long r = (long)response?.data;
                return r == 1;
            }
            else
            {
                var message = response?.msg ?? "保存失败";
                ToastManager.ShowToast(message);
            }
            return false;
        }

        private void OnCancel()
        {
            CloseDialog(new DialogResult(ButtonResult.Cancel));
        }

        public override void OnDialogOpened(IDialogParameters parameters)
        {
            if (parameters.Count > 0)
            {
                this.Title = "编辑用户";
                this.User = parameters.GetValue<UserDto>("data");
            }
            else
            {
                this.Title = "新建用户";
            }
        }
    }
}
